import type { IAuthLoginRes } from '@/api/types/login'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue' // 修复：导入 computed
import {
  refreshToken as _refreshToken,
  wxLogin as _wxLogin,
  getWxCode,
} from '@/api/login'
import { isValidLoginRes } from '@/api/types/login'
import { useUserStore } from './user'

// 初始化状态
const tokenInfoState: IAuthLoginRes = {
  userInfo: {
    tenantId: '',
    tenantName: '',
    departId: '',
    institutionId: '',
    id: '',
    userName: '',
    realName: '',
    employeeId: '',
    sysCompanyCode: '',
    sysOrgCode: '',
    systemType: null,
    avatar: null,
    abbreviation: '',
    admin: false,
  },
  tokenInfo: {
    tokenName: '',
    tokenValue: '',
    isLogin: false,
    loginId: '',
    loginType: '',
    tokenTimeout: 0,
    sessionTimeout: 0,
    tokenSessionTimeout: 0,
    tokenActivityTimeout: -1,
    loginDevice: 'default-device',
    tag: null,
  },
}

export const useTokenStore = defineStore(
  'token',
  () => {
    // 定义用户信息
    const tokenInfo = ref<IAuthLoginRes>({ ...tokenInfoState })
    // 设置token信息
    const setTokenInfo = (val: IAuthLoginRes) => {
      if (!isValidLoginRes(val)) {
        console.error('无效的登录响应格式:', val)
        return
      }

      tokenInfo.value = val

      // 存储token到本地，便于http请求使用
      uni.setStorageSync('token', val.tokenInfo.tokenValue)

      // 计算并存储过期时间
      const now = Date.now()
      const expireTime = now + val.tokenInfo.tokenTimeout * 1000
      uni.setStorageSync('tokenExpireTime', expireTime)
    }

    /**
     * 判断token是否过期
     */
    const isTokenExpired = computed(() => {
      if (!tokenInfo.value || !tokenInfo.value.tokenInfo || !tokenInfo.value.tokenInfo.isLogin) {
        return true
      }

      const now = Date.now()
      const expireTime = uni.getStorageSync('tokenExpireTime')

      if (!expireTime)
        return true
      return now >= expireTime
    })

    /**
     * 登录成功后处理逻辑
     * @param loginRes 登录返回的完整信息
     */
    async function _postLogin(loginRes: IAuthLoginRes) {
      setTokenInfo(loginRes)
      const userStore = useUserStore()
      try {
        // 调用获取用户信息接口，确保获取最新的用户信息
        await userStore.fetchUserInfo()
        console.log('登录后获取用户信息成功')
      }
      catch (error) {
        console.error('登录后获取用户信息失败:', error)
        // 如果获取用户信息失败，不影响登录状态，但会记录错误
      }
    }

    /**
     * 微信登录
     * 有的时候后端会用一个接口返回token和用户信息，有的时候会分开2个接口，一个获取token，一个获取用户信息
     * （各有利弊，看业务场景和系统复杂度），这里使用2个接口返回的来模拟
     * @returns 登录结果
     */
    const wxLogin = async () => {
      try {
        // 获取微信小程序登录的code
        const code = await getWxCode()
        console.log('微信登录-code: ', code)
        const res = await _wxLogin(code)
        console.log('微信登录-res: ', res)
        await _postLogin(res.data)
        uni.showToast({
          title: '登录成功',
          icon: 'success',
        })
        return res
      }
      catch (error) {
        console.error('微信登录失败:', error)
        uni.showToast({
          title: '微信登录失败，请重试',
          icon: 'error',
        })
        throw error
      }
    }

    /**
     * 退出登录 并 删除用户信息
     * 清除所有与登录相关的本地存储信息
     */
    const logout = async (): Promise<void> => {
      // 清除所有与登录相关的本地存储信息
      // 清除token和过期时间相关存储
      uni.removeStorageSync('token')
      uni.removeStorageSync('tokenExpireTime')
      uni.removeStorageSync('accessTokenExpireTime')
      uni.removeStorageSync('refreshTokenExpireTime')

      // 清除其他可能的登录相关信息（如果有）
      // 例如：登录记录、会话信息等

      // 重置状态
      console.log('退出登录-清除用户信息')
      tokenInfo.value = { ...tokenInfoState }

      // 清除用户信息
      const userStore = useUserStore()
      userStore.clearUserInfo()

      // 可选：清除所有cookies（对于H5平台）
      // #ifdef H5
      if (document && document.cookie) {
        const cookies = document.cookie.split(';')
        cookies.forEach((cookie) => {
          const eqPos = cookie.indexOf('=')
          const name = eqPos > -1 ? cookie.substring(0, eqPos) : cookie
          document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`
        })
      }
      // #endif
    }

    /**
     * 刷新token
     * @returns 刷新结果
     */
    const refreshToken = async () => {
      try {
        // 安全检查，确保token存在
        if (!tokenInfo.value || !tokenInfo.value.tokenInfo || !tokenInfo.value.tokenInfo.tokenValue) {
          throw new Error('无效的token')
        }

        // 注意：根据实际API调整刷新token的参数和调用方式
        const currentToken = tokenInfo.value.tokenInfo.tokenValue

        // 这里需要根据后端实际提供的刷新token接口调整参数
        // 当前假设refreshToken接口接受当前token作为参数
        const res = await _refreshToken(currentToken)
        console.log('刷新token-res: ', res)

        // 检查刷新结果是否有效
        if (isValidLoginRes(res)) {
          setTokenInfo(res)
          return res
        }
        else {
          throw new Error('刷新token返回无效格式')
        }
      }
      catch (error) {
        console.error('刷新token失败:', error)
        throw error
      }
    }

    /**
     * 获取有效的token
     * 注意：在computed中不直接调用异步函数，只做状态判断
     * 实际的刷新操作应由调用方处理
     */
    const getValidToken = computed(() => {
      // token已过期或未登录，返回空
      if (isTokenExpired.value || !tokenInfo.value.tokenInfo.isLogin) {
        return ''
      }

      return tokenInfo.value.tokenInfo.tokenValue || ''
    })

    /**
     * 检查是否有登录信息（不考虑token是否过期）
     */
    const hasLoginInfo = computed(() => {
      return tokenInfo.value
        && tokenInfo.value.tokenInfo
        && tokenInfo.value.tokenInfo.isLogin
        && !!tokenInfo.value.tokenInfo.tokenValue
    })

    /**
     * 检查是否已登录且token有效
     */
    const hasValidLogin = computed(() => {
      console.log('hasValidLogin', hasLoginInfo.value, !isTokenExpired.value)
      return hasLoginInfo.value && !isTokenExpired.value
    })

    /**
     * 尝试获取有效的token，如果过期且可刷新，则刷新token
     * @returns 有效的token或空字符串
     */
    const tryGetValidToken = async (): Promise<string> => {
      if (!getValidToken.value && tokenInfo.value && tokenInfo.value.tokenInfo && tokenInfo.value.tokenInfo.isLogin) {
        try {
          await refreshToken()
          return getValidToken.value
        }
        catch (error) {
          console.error('尝试刷新token失败:', error)
          return ''
        }
      }
      return getValidToken.value
    }

    /**
     * 登录处理方法
     * @param loginRes 登录返回的完整信息
     */
    const login = async (loginRes: IAuthLoginRes) => {
      await _postLogin(loginRes)
      return loginRes
    }

    return {
      // 核心API方法
      wxLogin,
      login,
      logout,

      // 认证状态判断（最常用的）
      hasLogin: hasValidLogin,

      // 内部系统使用的方法
      refreshToken,
      tryGetValidToken,
      validToken: getValidToken,

      // 调试或特殊场景可能需要直接访问的信息
      tokenInfo,
      setTokenInfo,
    }
  },
  {
    // 添加持久化配置，确保刷新页面后token信息不丢失
    persist: true,
  },
)
